// ScrollerLayout.cpp: implementation of the ScrollerLayout class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "ScrollerLayout.h"

#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif

IMPLEMENT_DYNAMIC(ScrollerLayout, AWTLayout)

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

ScrollerLayout::ScrollerLayout(Scroller* scroller)
{
	m_scroller = scroller;
	m_hbar = NULL;
	m_vbar = NULL;
	m_viewport = NULL;
	m_top = m_bottom = m_right = m_left = 0;
}

ScrollerLayout::~ScrollerLayout()
{

}

void ScrollerLayout::addLayoutComponent(CString* name, AWTComponent* comp) 
{
	if(comp->IsKindOf(RUNTIME_CLASS(AWTScrollbar))) 
	{
		AWTScrollbar* sbar = (AWTScrollbar*)comp;

		if(sbar->getOrientation() == AWTScrollbar::VERTICAL) 
		{
			m_vbar = sbar;
			m_vbarPosition = *name;
		}
		else 
		{
			m_hbar = sbar;
			m_hbarPosition = *name;
		}
	}
	else 
	{
		m_viewport = comp;
	}
}

void ScrollerLayout::removeLayoutComponent(AWTComponent* comp) 
{
  if(comp == m_vbar) m_vbar = NULL;
  if(comp == m_hbar) m_hbar = NULL;
  if(comp == m_viewport) m_viewport = NULL;
}

CSize ScrollerLayout::preferredLayoutSize(AWTContainer* parent) 
{
	CSize ps(0,0);
	AWTInsets insets = parent->getInsets();

  if(m_vbar != NULL && m_vbar->isVisible()) 
	{
		CSize d = m_vbar->getPreferredSize();
    ps.cx  = d.cx;
		ps.cy = d.cy;
  }
  if(m_hbar != NULL && m_hbar->isVisible()) 
	{
		CSize d = m_hbar->getPreferredSize();
    ps.cx = d.cx;
		ps.cy = d.cy + ps.cy;
  }
  if(m_viewport != NULL && m_viewport->isVisible()) 
	{
		CSize d = m_viewport->getPreferredSize();
    ps.cx = max(d.cx, ps.cx);
    ps.cy = max(d.cy, ps.cy);
  }
	ps.cx += insets.left + insets.right;
	ps.cy += insets.top + insets.bottom;
  return ps;
}

CSize ScrollerLayout::minimumLayoutSize(AWTContainer* parent) 
{
	CSize ps(0,0);
	AWTInsets insets = parent->getInsets();

	if(m_vbar != NULL && m_vbar->isVisible()) 
	{
		CSize d = m_vbar->getMinimumSize();
		ps.cx  = d.cx;
		ps.cy = d.cy;
	}
	if(m_hbar != NULL && m_hbar->isVisible()) 
	{
		CSize d = m_hbar->getMinimumSize();
		ps.cx  = d.cx;
		ps.cy = d.cy + ps.cy;
	}
	if(m_viewport != NULL && m_viewport->isVisible()) 
	{
		CSize d = m_viewport->getMinimumSize();
		ps.cx = max(d.cx, ps.cx);
		ps.cy = max(d.cy, ps.cy);
	}
	ps.cx += insets.left + insets.right;
	ps.cy += insets.top + insets.bottom;
	return ps;
}

void ScrollerLayout::layoutContainer(AWTContainer* target) 
{
  AWTInsets insets = target->getInsets();
  CSize targetSize = target->getSize();

  m_top = insets.top;
  m_bottom = targetSize.cy - insets.bottom;
  m_left = insets.left;
  m_right = targetSize.cx - insets.right;

  m_scroller->manageScrollbars();

  reshapeHorizontalScrollbar();
  reshapeVerticalScrollbar  ();
  reshapeViewport           ();

  m_scroller->setScrollbarValues();
}

void ScrollerLayout::reshapeHorizontalScrollbar() 
{
	if(m_hbar != NULL && m_hbar->isVisible()) 
	{
		if(m_hbarPosition == "North") 
		{
			CSize d = m_hbar->getPreferredSize();
			m_hbar->setBounds(m_left, m_top, m_right - m_left, d.cy);
			m_top += d.cy;
		}
		else 
		{  // South
			CSize d = m_hbar->getPreferredSize();
			m_hbar->setBounds(m_left, m_bottom - d.cy, m_right - m_left, d.cy);
			m_bottom -= d.cy;
		}
	}
}

void ScrollerLayout::reshapeVerticalScrollbar() 
{
  if(m_vbar != NULL && m_vbar->isVisible()) 
	{
    if(m_vbarPosition == "East")
		{
      CSize d = m_vbar->getPreferredSize();
      m_vbar->setBounds(m_right - d.cx, m_top, d.cx, m_bottom - m_top);
      m_right -= d.cx;
    }
    else 
		{ // West
      CSize d = m_vbar->getPreferredSize();
      m_vbar->setBounds(m_left, m_top, d.cx, m_bottom - m_top);
      m_left += d.cx;
    }
  }
}

void ScrollerLayout::reshapeViewport() 
{
	if(m_viewport != NULL && m_viewport->isVisible()) 
	{
		m_viewport->setBounds(m_left, m_top, m_right - m_left, m_bottom - m_top);
		m_viewport->validate();
	}
}
